/**
 * Copyright 2018 人人开源 http://www.renren.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package io.renren.modules.sys.service.impl;


import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import io.renren.common.utils.Constant;
import io.renren.common.utils.MapUtils;
import io.renren.common.utils.UUIDGenerator;
import io.renren.modules.sys.dao.MenuDao;
import io.renren.modules.sys.entity.Menu;
import io.renren.modules.sys.entity.User;
import io.renren.modules.sys.service.MenuService;
import io.renren.modules.sys.service.RoleMenuService;
import io.renren.modules.sys.service.UserService;
import io.renren.modules.sys.vo.MenuTree;


@Service
public class MenuServiceImpl extends ServiceImpl<MenuDao, Menu> implements MenuService {
	
	@Autowired
	private UserService sysUserService;
	@Autowired
	private RoleMenuService sysRoleMenuService;
	
	@Override
	public List<Menu> queryListParentId(String parentId, List<String> menuIdList) {
		List<Menu> menuList = queryListParentId(parentId);
		if(menuIdList == null){
			return menuList;
		}
		
		List<Menu> userMenuList = new ArrayList<>();
		for(Menu menu : menuList){
			if(menuIdList.contains(menu.getMenuId())){
				userMenuList.add(menu);
			}
		}
		return userMenuList;
	}

	@Override
	public List<Menu> queryListParentId(String parentId) {
		return baseMapper.queryListParentId(parentId);
	}

	@Override
	public List<Menu> queryNotButtonList() {
		return baseMapper.queryNotButtonList();
	}

	@Override
	public List<Menu> getUserMenuList(String userId) {
		//系统管理员，拥有最高权限
		if(Constant.SUPER_ADMIN.equals(userId)){
			return getAllMenuList(null);
		}
		
		//用户菜单列表
		List<String> menuIdList = sysUserService.queryAllMenuId(userId);
		return getAllMenuList(menuIdList);
	}

	@Override
	public void delete(String menuId){
		//删除菜单
		this.deleteById(menuId);
		//删除菜单与角色关联
		sysRoleMenuService.deleteByMap(new MapUtils().put("menu_id", menuId));
	}

	/**
	 * 获取所有菜单列表
	 */
	private List<Menu> getAllMenuList(List<String> menuIdList){
		//查询根菜单列表
		List<Menu> menuList = queryListParentId("0", menuIdList);
		//递归获取子菜单
		getMenuTreeList(menuList, menuIdList);
		
		return menuList;
	}

	/**
	 * 递归
	 */
	private List<Menu> getMenuTreeList(List<Menu> menuList, List<String> menuIdList){
		List<Menu> subMenuList = new ArrayList<Menu>();
		
		for(Menu entity : menuList){
			//目录
			if(entity.getType() == Constant.MenuType.CATALOG.getValue()){
				entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList), menuIdList));
			}
			subMenuList.add(entity);
		}
		
		return subMenuList;
	}

	
	@Override
	public List<Menu> selectListByUser(User user) {
		List<Menu> menuList = null;
		//判断是否为超级管理员
		if(Constant.SUPER_ADMIN.equals(user.getUserId()) ) {
			menuList = this.selectList(null);
		}else {
			menuList = baseMapper.selectListByUser(user.getUserId());
		}
		
		for(Menu Menu : menuList){
			Menu parentMenuEntity = this.selectById(Menu.getParentId());
			if(parentMenuEntity != null){
				Menu.setParentName(parentMenuEntity.getName());
			}
		}
		return menuList;
	}

	@Override
	public List<MenuTree> selectMenuTreeByUser(User user) {
		
		List<Menu> menuList = null;
		List<MenuTree> menuTrees = new ArrayList<MenuTree>();
		MenuTree mtree = null;
		//判断是否为超级管理员
		if(Constant.SUPER_ADMIN.equals(user.getUserId()) ) {
			menuList = this.selectList(null);
		}else {
			menuList = baseMapper.selectListByUser(user.getUserId());
		}
		
		//获取root菜单
		for(Menu m : menuList) {
			if(StringUtils.equals("0", m.getParentId())) {
				mtree = new MenuTree();
				BeanUtils.copyProperties(m, mtree);
				menuTrees.add(mtree);
			}
		}
		
		//设置子节点
		for(MenuTree mt : menuTrees) {
			mt.setChildren(getChildren(mt.getMenuId(), menuList));
		}
				
		return menuTrees;
	}
	
	/**
	 * 递归子节点
	 * @param parentId
	 * @param dgps
	 * @return
	 */
	private List<MenuTree> getChildren(String parentId, List<Menu> menus) {
		List<MenuTree> mts = new ArrayList<MenuTree>();
		MenuTree mt = null;
		for (Menu m : menus) {
			if (StringUtils.equals(parentId, m.getParentId())) {
				mt = new MenuTree();
				BeanUtils.copyProperties(m, mt);
				mts.add(mt);
			}
		}

		for (MenuTree mtree : mts) {
			// 递归
			mtree.setChildren(getChildren(mtree.getMenuId(), menus));
		}

		return mts;
	}

	@Override
	public Menu saveMenu(Menu menu) {
		
		menu.setMenuId(UUIDGenerator.getUUID());
		//当前菜单不是目录则获取上级菜单
		if(menu.getType() == 0) {
			menu.setParentId("0");
			menu.setPath(menu.getMenuId());
		}else {
			Menu parent = this.selectById(menu.getParentId());
			menu.setPath(parent.getPath()+","+menu.getMenuId());
		}
		
		menu.setLevel(menu.getPath().split(",").length);
		this.insert(menu);
		return menu;
	}

	@Override
	public List<MenuTree> queryNotButtonTree() {
		
		List<Menu> menuList = baseMapper.queryNotButtonList();
		List<MenuTree> menuTrees = new ArrayList<MenuTree>();
		MenuTree mtree = null;
		//获取root菜单
		for(Menu m : menuList) {
			if(StringUtils.equals("0", m.getParentId())) {
				mtree = new MenuTree();
				BeanUtils.copyProperties(m, mtree);
				menuTrees.add(mtree);
			}
		}
		
		//设置子节点
		for(MenuTree mt : menuTrees) {
			mt.setChildren(getChildren(mt.getMenuId(), menuList));
		}
				
		return menuTrees;
	}

}
